package truerefactor.graph;

import java.util.HashSet;
import java.util.Set;

/**
 * SetOperations - A Wrapper Class defining the basic operations from set theory
 * using the Java Collections Set Classes.
 * 
 * @author Isaac Griffith
 */
public class SetOperations {

    /**
     * @param <T>
     * @param setA
     *            set A
     * @param setB
     *            set B
     * @return a set consisting of all the members in both set A and set B
     */
    public static <T> Set<T> union(Set<T> setA, Set<T> setB)
    {
        Set<T> tmp = new HashSet<T>(setA);
        tmp.addAll(setB);
        return tmp;
    }

    /**
     * @param <T>
     * @param setA
     *            set A
     * @param setB
     *            set B
     * @return a set consisting of all the members of set A that are also
     *         members of set B
     */
    public static <T> Set<T> intersection(Set<T> setA, Set<T> setB)
    {
        Set<T> tmp = new HashSet<T>();
        for (T x : setA)
            if (setB.contains(x))
                tmp.add(x);
        return tmp;
    }

    /**
     * @param <T>
     * @param setA
     *            set A
     * @param setB
     *            set B
     * @return set consisting of all members of A not in B
     */
    public static <T> Set<T> difference(Set<T> setA, Set<T> setB)
    {
        Set<T> tmp = new HashSet<T>(setA);
        tmp.removeAll(setB);
        return tmp;
    }

    /**
     * @param <T>
     * @param setA
     *            set A
     * @param setB
     *            set B
     * @return a set consisting of all members of A and B that are not in both A
     *         and B
     */
    public static <T> Set<T> symDifference(Set<T> setA, Set<T> setB)
    {
        Set<T> tmpA;
        Set<T> tmpB;

        tmpA = union(setA, setB);
        tmpB = intersection(setA, setB);
        return difference(tmpA, tmpB);
    }

    /**
     * @param <T>
     * @param setA
     * @param setB
     * @return
     */
    public static <T> boolean isSubset(Set<T> setA, Set<T> setB)
    {
        return setB.containsAll(setA);
    }

    /**
     * Determines whether one set is the super set of another
     * 
     * @param <T>
     * @param setA
     *            set under question if it is the super set of the other set
     * @param setB
     *            set
     * @return true if the first parameter is the super set of the second
     *         parameter
     */
    public static <T> boolean isSuperset(Set<T> setA, Set<T> setB)
    {
        return setA.containsAll(setB);
    }
}